package cn.edu.scau.cmi.liangzijian.hibernate;

import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;

import org.springframework.context.ApplicationContext;

import cn.edu.scau.cmi.liangzijian.hibernate.dao.StudentDAO;
import cn.edu.scau.cmi.liangzijian.hibernate.dao.TeacherDAO;
import cn.edu.scau.cmi.liangzijian.hibernate.domain.Student;
import cn.edu.scau.cmi.liangzijian.hibernate.domain.Teacher;
import cn.edu.scau.cmi.liangzijian.hibernate.util.ApplicationContextUtil;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;


public class UIController {

    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private TextArea board;

    @FXML
    private TextField name1;

    @FXML
    private TextField name2;

    @FXML
    private ComboBox<String> obj2;

    @FXML
    private ComboBox<String> obj3;

    @FXML
    private ComboBox<String> student4;

    @FXML
    private ComboBox<String> student5;

    @FXML
    private ComboBox<String> teacher4;

    @FXML
    private ComboBox<String> teacher5;

    @FXML
    private Label tip1;

    @FXML
    private Label tip2;
    
    @FXML
    private Label tip3;
    
    @FXML
    private Label tip4;
    
    @FXML
    private Label tip5;
    
    @FXML
    private ComboBox<String> type1;

    @FXML
    private ComboBox<String> type2;

    @FXML
    private ComboBox<String> type3;
    
    private List teachers;
    
    private List students;
    
    @FXML
    void add(MouseEvent event) {
    	String typeString = type1.getValue();
    	String nameString = name1.getText().trim();
    	
    	if(!nameString.equals("")) {
    		if(nameString.length() < 1 || nameString.length() > 20) {
    			tip1.setText("长度为1到20个字符");
    		} else {
    			if(typeString.equals("student")) {
	    			StudentDAO sd = getStudentDAO();
	    			
	    			Student student = new Student();
	    			student.setName(nameString);
	    			
	    			try {
	    				sd.insert(student);
	    				tip1.setText("添加成功");
	    				name1.setText("");
	    				
	    				students.add(student);
	    				refleshAll();
	    			} catch(RuntimeException re) {
	    				tip1.setText("添加失败");
	    			}
    			} else if(typeString.equals("teacher")) {
    				TeacherDAO td = getTeacherDAO();
	    			
	    			Teacher teacher = new Teacher();
	    			teacher.setName(nameString);
	    			
	    			try {
	    				td.insert(teacher);
	    				tip1.setText("添加成功");
	    				name1.setText("");
	    				
	    				teachers.add(teacher);
	    				refleshAll();
	    			} catch(RuntimeException re) {
	    				tip1.setText("添加失败");
	    			}
    			}
    		}
    	}
    }
    
    @FXML
    void update(MouseEvent event) {
    	String type = type2.getValue();
    	String idString = obj2.getValue();
    	String newName = name2.getText().trim();
    	
		if(type == null || type.equals("")) {
			tip2.setText("请选择角色");
			return;
		}
		if(idString == null || idString.equals("")) {
			tip2.setText("请选择Id");
			return;
		}
		if(newName == null || newName.equals("")) {
			tip2.setText("请输入名称");
			return;
		}
		if(newName.length() < 1 || newName.length() > 20) {
			tip2.setText("长度为1到20个字符");
			return;
		}
		
		if(type.equals("student")) {
			for(Object obj : students) {
				if(((Student)obj).getId() == Integer.valueOf(idString)) {
					((Student)obj).setName(newName);
					
					try {
						StudentDAO studentDAO = getStudentDAO();
						studentDAO.update((Student)obj);
						
						name2.setText("");
						tip2.setText("更新成功");
						
						refleshAll();
						showAll();
			
						return;
					} catch(RuntimeException re){
					}
				}
			}
		} else if(type.equals("teacher")) {
			for(Object obj : teachers) {
				if(((Teacher)obj).getId() == Integer.valueOf(idString)) {
					((Teacher)obj).setName(newName);
					
					try {
						TeacherDAO teacherDAO = getTeacherDAO();
						teacherDAO.update((Teacher)obj);
						
						name2.setText("");
						tip2.setText("更新成功");
						
						refleshAll();
						showAll();
						
						return;
					} catch(RuntimeException re){
					}
				}
			}
		}    
    }
    
    @FXML
    void delete(MouseEvent event) {
    	String type = type3.getValue();
    	String idString = obj3.getValue();
    	
		if(type == null || type.equals("")) {
			tip3.setText("请选择角色");
			return;
		}
		if(idString == null || idString.equals("")) {
			tip3.setText("请选择Id");
			return;
		}
		
		if(type.equals("student")) {
			for(Object obj : students) {
				if(((Student)obj).getId() == Integer.valueOf(idString)) {
					
					try {
						StudentDAO studentDAO = getStudentDAO();
						studentDAO.delete((Student)obj);
						
						tip3.setText("删除成功");
						
						students.remove(obj);
						
						refleshAll();
						showAll();
						
						return;
					} catch(RuntimeException re){
					}
				}
			}
	
		} else if(type.equals("teacher")) {
			for(Object obj : teachers) {
				if(((Teacher)obj).getId() == Integer.valueOf(idString)) {
					
					try {
						Set<Student> students = ((Teacher)obj).getStudents();
						for(Student std : students) {
							std.setTeacher(null);
						}
						
						TeacherDAO teacherDAO = getTeacherDAO();
						teacherDAO.delete((Teacher)obj);
						
						tip3.setText("删除成功");
						
						teachers.remove(obj);
						
						refleshAll();
						showAll();
						
						return;
					} catch(RuntimeException re){
					}
				}
			}
			
			
		}    
    }

    @FXML
    void stdntChsTchr(MouseEvent event) {
    	String studentIdString = student4.getValue();
    	String teacherIdString = teacher4.getValue();
    	
    	if(studentIdString == null || studentIdString.equals("")) {
    		tip4.setText("请选择学生Id");
    		return;
    	}
    	if(teacherIdString == null || teacherIdString.equals("")) {
    		tip4.setText("请选择教师Id");
    		return;
    	}
    	
    	Student targetStudent = null;
    	Teacher targetTeacher = null;
    	
    	for(Object obj : students) {
			if(((Student)obj).getId() == Integer.valueOf(studentIdString)) {
				targetStudent = (Student)obj;
				break;
			}
		}
    	
    	for(Object obj : teachers) {
			if(((Teacher)obj).getId() == Integer.valueOf(teacherIdString)) {
				targetTeacher = (Teacher)obj;
				break;
			}
		}
    	
    	if(targetStudent == null || targetTeacher == null) {
    		return;
    	} 
    	
    	targetStudent.setTeacher(targetTeacher);
    	
    	try {
			StudentDAO studentDAO = getStudentDAO();
			studentDAO.update(targetStudent);
			
			tip4.setText("选择或修改成功");
						
			showAll();
			
			return;
		} catch(RuntimeException re){
		}
    	
    }

    @FXML
    void tchrChsStdnt(MouseEvent event) {
    	String studentIdString = student5.getValue();
    	String teacherIdString = teacher5.getValue();
    	
    	if(teacherIdString == null || teacherIdString.equals("")) {
    		tip5.setText("请选择教师Id");
    		return;
    	}
    	if(studentIdString == null || studentIdString.equals("")) {
    		tip5.setText("请选择学生Id");
    		return;
    	}
    	
    	Student targetStudent = null;
    	Teacher targetTeacher = null;
    	
    	for(Object obj : students) {
			if(((Student)obj).getId() == Integer.valueOf(studentIdString)) {
				targetStudent = (Student)obj;
				break;
			}
		}
    	
    	for(Object obj : teachers) {
			if(((Teacher)obj).getId() == Integer.valueOf(teacherIdString)) {
				targetTeacher = (Teacher)obj;
				break;
			}
		}
    	
    	if(targetStudent == null || targetTeacher == null) {
    		return;
    	} 
    	
    	targetStudent.setTeacher(targetTeacher);
    	
    	try {
    		StudentDAO studentDAO = getStudentDAO();
			studentDAO.update(targetStudent);
			
			tip5.setText("选择或修改成功");
						
			showAll();
			
			return;
		} catch(RuntimeException re){
		}
    }

    @FXML
    void initialize() {
        assert board != null : "fx:id=\"board\" was not injected: check your FXML file 'UI.fxml'.";
        assert name1 != null : "fx:id=\"name1\" was not injected: check your FXML file 'UI.fxml'.";
        assert name2 != null : "fx:id=\"name2\" was not injected: check your FXML file 'UI.fxml'.";
        assert obj2 != null : "fx:id=\"obj2\" was not injected: check your FXML file 'UI.fxml'.";
        assert obj3 != null : "fx:id=\"obj3\" was not injected: check your FXML file 'UI.fxml'.";
        assert student4 != null : "fx:id=\"student4\" was not injected: check your FXML file 'UI.fxml'.";
        assert student5 != null : "fx:id=\"student5\" was not injected: check your FXML file 'UI.fxml'.";
        assert teacher4 != null : "fx:id=\"teacher4\" was not injected: check your FXML file 'UI.fxml'.";
        assert teacher5 != null : "fx:id=\"teacher5\" was not injected: check your FXML file 'UI.fxml'.";
        assert tip1 != null : "fx:id=\"tip1\" was not injected: check your FXML file 'UI.fxml'.";
        assert type1 != null : "fx:id=\"type1\" was not injected: check your FXML file 'UI.fxml'.";
        assert type2 != null : "fx:id=\"type2\" was not injected: check your FXML file 'UI.fxml'.";
        assert type3 != null : "fx:id=\"type3\" was not injected: check your FXML file 'UI.fxml'.";
    
        refleshList();
        showAll();
        
        type1.setItems(FXCollections.observableArrayList("student", "teacher"));
        
        type2.setItems(FXCollections.observableArrayList("student", "teacher"));
    	type2.valueProperty().addListener(new ChangeListener() {
			@Override
			public void changed(ObservableValue observable, Object oldValue, Object newValue) {
				if(newValue == null)
					return;
				
				if(newValue.equals("teacher")) {
					obj2.getItems().clear();
					for(Object obj : teachers) {
						obj2.getItems().add(String.valueOf(((Teacher)obj).getId()));
					}
				} else if(newValue.equals("student")) {
					obj2.getItems().clear();
					for(Object obj : students) {
						obj2.getItems().add(String.valueOf(((Student)obj).getId()));
					}
				}
			}    	
    	});
        
    	type3.setItems(FXCollections.observableArrayList("student", "teacher"));
    	type3.valueProperty().addListener(new ChangeListener() {
			@Override
			public void changed(ObservableValue observable, Object oldValue, Object newValue) {
				if(newValue == null)
					return;
				
				if(newValue.equals("teacher")) {
					obj3.getItems().clear();
					for(Object obj : teachers) {
						obj3.getItems().add(String.valueOf(((Teacher)obj).getId()));
					}
				} else if(newValue.equals("student")) {
					obj3.getItems().clear();
					for(Object obj : students) {
						obj3.getItems().add(String.valueOf(((Student)obj).getId()));
					}
				}
			}    	
    	});
    	
    	refleshStdntChsTchrPart();
    	refleshTchrChsStdntPart();
    }
    
    private void refleshList() {
    	StudentDAO studentDAO = getStudentDAO();
    	TeacherDAO teacherDAO = getTeacherDAO();
    	
    	try {
    		teachers = teacherDAO.findAll();
    		students = studentDAO.findAll();
    		
    	} catch(RuntimeException re) {
    		board.appendText("数据库查询异常");
    		return;
    	}
    }
    
    private void refleshAll() {
    	showAll();
    	refleshUpdatePart();
    	refleshDeletePart();
    	refleshStdntChsTchrPart();
    	refleshTchrChsStdntPart();
    }
    
    private void showAll() {
    	board.clear();
    		
    	board.appendText("教师信息：\n");
    	for(Object obj : teachers) {
    		board.appendText((Teacher)obj + "\n");
    	}
    	
    	board.appendText("\n学生信息：\n");
    	for(Object obj : students) {
    		board.appendText((Student)obj + "\n");
    	}
    }
    
    private void refleshUpdatePart() {
    	String tmpString = type2.getValue();
    	type2.setValue("");
    	type2.setValue(tmpString);
    }
    
    private void refleshDeletePart() {
    	String tmpString = type3.getValue();
    	type3.setValue("");
    	type3.setValue(tmpString);
    }
    
    private void refleshStdntChsTchrPart() {
    	student4.getItems().clear();
    	teacher4.getItems().clear();
    	
    	for(Object obj : students) {
    		student4.getItems().add(String.valueOf(((Student)obj).getId()));
    	}
    	
    	for(Object obj : teachers) {
    		teacher4.getItems().add(String.valueOf(((Teacher)obj).getId()));
    	}
    }
    
    private void refleshTchrChsStdntPart() {
    	student5.getItems().clear();
    	teacher5.getItems().clear();
    	
    	for(Object obj : students) {
    		student5.getItems().add(String.valueOf(((Student)obj).getId()));
    	}
    	
    	for(Object obj : teachers) {
    		teacher5.getItems().add(String.valueOf(((Teacher)obj).getId()));
    	}
    }
    
    private StudentDAO getStudentDAO() {
    	return (StudentDAO)getApplicationContext().getBean("studentDAO");
    }
    
    private TeacherDAO getTeacherDAO() {
    	return (TeacherDAO)getApplicationContext().getBean("teacherDAO");
    }
    
    private static ApplicationContext getApplicationContext() {
    	return ApplicationContextUtil.getInstance();
    }
    
}
